home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / pmode / 386p_200 / 386keyb.asm < prev    next >
Encoding:
Assembly Source File  |  1995-01-11  |  9.2 KB  |  324 lines

  1.  
  2. .386P
  3. code32 segment para public use32
  4.        assume cs:code32,ds:code32
  5. include 386power.inc
  6. include 386sys.inc     
  7.  
  8.  
  9. ; RAW KEYBOARD I/O
  10. ; 32bit section, Keyboard ISR for raw keyboard input
  11.  
  12. ; Raw KeyBoard table
  13. ; Every key "description" is made of two consecutive bytes
  14. ; if a key has a keyboard scancode K
  15. ; address:     
  16. ; _RKB+(K)  bit   meaning:       description:
  17. ;             0   IS_PRESSED     0 == key K is currently not pressed
  18. ;                                1 == key K is currently     pressed
  19. ;
  20. ;             1   TOUCHED        0 == key K has not been pressed 
  21. ;                                     since last time you cleared this bit.
  22. ;                                1 == key K has been pressed
  23. ;
  24. ; Use IS_PRESSED for "raw" control (i.e cursor keys in a game)
  25. ; and TOUCHED (but clear it before!!) for "keyboard-like"  control
  26. ; when you have to choose items in a menu or when
  27. ; you have to check special "toggle" keys that may be pressed anytime
  28. ; (i.e. the all time high ESC key)
  29.         public _KeyNames,_NotAKey
  30.  
  31. _KeyNames dd offset knt
  32. _NotAKey  dd offset boh
  33. ; n.b. the character code zero is "no key"
  34. ;      so the character number zero is used as a standard message
  35. ;      for key selection "choose key"
  36.  
  37. knt dd nada,esc,uno,due,tre,quattro,cinque,sei
  38.     dd sette,otto,nove,zero,meno,piu,backspace,tab
  39.     dd q,w,e,r,t,y,u,i
  40.     dd o,p,aquad,cquad,enter,ctrl,a,s
  41.     dd d,f,g,h,j,k,l,puntovirgola_2punti
  42.     dd apice_virgolette,apice_tilde,lshift,slash_bar,z,x,c,v
  43.     dd b,n,m,virgola_maggiore,punto_minore,backslash_interrogativo,rshift,k_per
  44.     dd alt,spazio,capslock,f1,f2,f3,f4,f5
  45.     dd f6,f7,f8,f9,f10,numlock,scrolllock,k_home
  46.     dd k_up,k_pgup,k_meno,k_left,k_five,k_right,k_piu,k_end
  47.     dd k_down,k_pgdn,k_ins,k_del,boh,boh,lshift,f11
  48.     ; boh = code 54h..55h unknow , 56h looks like a left_shift duplicate
  49.     dd f12, boh,boh,boh,boh,boh,boh,boh
  50.     dd boh,boh,boh,boh,boh,boh,boh,boh
  51.     dd boh,boh,boh,boh,boh,boh,boh,key_macro
  52.     dd boh,boh,boh,boh,boh,boh,boh,boh
  53.     dd boh,boh,boh,boh,boh,boh,boh,boh
  54.  
  55. boh     db 'unknown key code',0
  56. nada    db 'not defined',0
  57. esc     db 'ESC',0
  58. uno     db '1',0
  59. due     db '2',0
  60. tre     db '3',0
  61. quattro db '4',0
  62. cinque  db '5',0
  63. sei     db '6',0
  64. sette   db '7',0
  65. otto    db '8',0
  66. nove    db '9',0
  67. zero    db '0',0
  68. piu     db '+',0
  69. meno    db '-',0
  70. q       db 'q',0
  71. w       db 'w',0
  72. e       db 'e',0
  73. r       db 'r',0
  74. t       db 't',0
  75. y       db 'y',0
  76. u       db 'u',0
  77. i       db 'i',0
  78. o       db 'o',0
  79. p       db 'p',0
  80. a       db 'a',0
  81. s       db 's',0
  82. d       db 'd',0
  83. f       db 'f',0
  84. g       db 'g',0
  85. h       db 'h',0
  86. j       db 'j',0
  87. k       db 'k',0
  88. l       db 'l',0
  89. z       db 'z',0
  90. x       db 'x',0
  91. c       db 'c',0
  92. v       db 'v',0
  93. b       db 'b',0
  94. n       db 'n',0
  95. m       db 'm',0
  96. aquad   db '[',0
  97. cquad   db ']',0
  98. tab     db 'TAB',0
  99.  
  100. backspace               db 'BACKSPACE',0
  101. enter                   db 'ENTER',0
  102. ctrl                    db 'CTRL',0
  103. puntovirgola_2punti     db ';',0
  104. apice_virgolette        db '"',0
  105. apice_tilde             db '~',0
  106. lshift                  db 'LEFT SHIFT',0
  107. slash_bar               db '\',0
  108. virgola_maggiore        db ',',0
  109. punto_minore            db '.',0
  110. backslash_interrogativo db '/',0
  111. rshift                  db 'RIGHT SHIFT',0
  112. k_per                   db 'KEYPAD *',0
  113. alt                     db 'ALT',0
  114. spazio                  db 'SPACE',0
  115. capslock                db 'CAPSLOCK',0
  116.  
  117. f1                     db 'fn 1',0
  118. f2                     db 'fn 2',0
  119. f3                     db 'fn 3',0
  120. f4                     db 'fn 4',0
  121. f5                     db 'fn 5',0
  122. f6                     db 'fn 6',0
  123. f7                     db 'fn 7',0
  124. f8                     db 'fn 8',0
  125. f9                     db 'fn 9',0
  126. f10                    db 'fn 10',0
  127. f11                    db 'fn 11',0
  128. f12                    db 'fn 12',0
  129.  
  130. numlock       db 'NUMLOCK',0
  131. scrolllock    db 'SCROLL LOCK',0
  132. k_home        db 'HOME',0
  133. k_up          db 'CURSOR UP',0
  134. k_pgup        db 'PAGE UP',0
  135. k_meno        db 'keypad -',0
  136. k_left        db 'CURSOR LEFT',0
  137. k_five        db 'keypad 5',0
  138. k_right       db 'CURSOR RIGHT',0
  139. k_piu         db 'keypad +',0
  140. k_end         db 'END',0
  141. k_down        db 'CURSOR DOWN',0
  142. k_pgdn        db 'PAGE DOWN',0
  143. k_ins         db 'INS',0
  144. k_del         db 'DEL',0
  145. key_macro     db 'MACRO KEY',0
  146.  
  147. _RKB  db      128 dup(0)
  148.  
  149. RKBPressed db  0 ; 0 == no keys pressed since last time you reset this flag
  150.                   ; 1 == something happened, a key has been pressed
  151.                   ; (this is like a "general" TOUCHED flag)
  152. ezero  db 0
  153.  
  154. IRQ1_ISR:
  155.         cli
  156.         push    eax
  157.         push    ebx
  158.         push    ds
  159.         mov     ds,cs:_SelData
  160.  
  161.     in      al,60h          ; get scan code
  162.  
  163.         movzx   ebx,al          ; move scan code to index register
  164.  
  165.     in      al,61h          ; get control code
  166.         push    eax
  167.     or      al,80h          ; clear keyboard of interrupt:
  168.     out     61h,al          ;
  169.         pop     eax             ;   first send control byte with inverted MSB
  170.     out     61h,al          ;   then send plain control byte
  171.  
  172.         mov     al,EOI          ; send generic EOI to
  173.         out     PIC0_CTRL,al    ;   PIC
  174.                 ; enabling other interrupts
  175.  
  176.         cmp al,0E0h ; the terrific escape code
  177.         jne good_k
  178.         mov ezero,1
  179.         jmp short guuk
  180. good_k:
  181.         cmp ezero,0    ; does previous key was multi-byte prefix ?
  182.         je noezero     ;
  183.         mov ezero,0
  184.         ; skip false keypresses
  185.         cmp al,0AAh
  186.         je guuk
  187.         cmp al,02ah
  188.         je guuk
  189.         cmp al,0B6h
  190.         je guuk
  191.         cmp al,036h
  192.         je guuk
  193. noezero:
  194.         mov al,bl
  195.         and bl,07Fh
  196.     ; if the key was released, the high bit is set in the scan code
  197.  
  198.         ; first of all, let's assume it was released
  199.         mov byte ptr[ebx+offset _RKB],02h ; reset "Is being pressed" flag
  200.                                           ; and set again "Has been pressed"
  201.                                           ; N.B. FOLLOW STRICTLY THIS METHOD
  202.                                           ;
  203.         
  204.         rol al,1           ; has it been released ?
  205.         jc  key_released   ;
  206.         ; no, it has been pressed
  207.         mov byte ptr [ebx+offset _RKB],03h ; set "Is being pressed" flag
  208.                                            ; and "Has been pressed" flag
  209. key_released:
  210.         mov RKBPressed,1     ; state of keyboard has changed
  211. guuk:
  212.         sti
  213.         pop ds
  214.         pop ebx
  215.         pop eax
  216.         iretd 
  217.  
  218.         public _WaitKey
  219. _WaitKey dd offset WaitKey 
  220.  
  221. WaitKey:
  222.         ; WAITS UNTIL A KEY IS PRESSED
  223.         ; then returns pointer to keyboard table
  224.         mov RKBPressed,0
  225. @waitmore:        
  226.         test RKBPressed,1
  227.         jz @waitmore        
  228.         mov eax,offset _RKB
  229.         ret
  230.         
  231.  
  232.  
  233. KEYB_EXIT: ; 386keyb termination code
  234.         ; restore default keyboard handler and rate
  235.         call KeybAsciiMode     ; restore default keyboard handler
  236.         ; THIS CODE NOW HAS BEEN MOVED BACK TO THE MAIN EXIT ROUTINE
  237.         ; BECAUSE IT BOMBED UNDER PROT. MODE WITH MY ANTIVIRUS LOADED
  238.         ;sti
  239.         ; now set typematic rate to the default values
  240.         mov V86ax,0305h ; typematic_rate set_rate
  241.         mov V86bx,000Ch ; 00 == 250msec delay_value
  242.                         ; 0C == 10char/sec repeat_rate
  243.         mov al,16h
  244.         call _ExecINT
  245.         ;cli
  246.         ret
  247.         
  248.         public _KeybInst
  249. _KeybInst dd offset InstallRKB
  250.  
  251. plaintty dd 0
  252.  
  253. InstallRKB:
  254.         pushad
  255.  
  256.         ; Now set typematic rate to the lowest values
  257.         mov V86ax,0305h ; typematic_rate set_rate
  258.         mov V86bx,001Fh ; 00 == 250msec delay_value  
  259.                         ; 1F == 2char/sec repeat_rate
  260.         mov al,16h
  261.         call _ExecINT
  262.  
  263.         mov bl,1
  264.         call _GetIRQ
  265.         mov plaintty,edx    ; get the default irq handler
  266.         
  267.         mov eax, offset KEYB_EXIT   ; set exit function
  268.         call _OnExit                ;
  269.                 
  270.         mov eax,0
  271.         mov edi,offset _RKB
  272.         mov ecx,32 ; 128bytes == 32 dwords
  273.         rep stosd
  274.  
  275.         call _KeybRawMode
  276.  
  277.         popad
  278.         ret
  279.  
  280.         public _KeybAsciiMode
  281. _KeybAsciiMode dd offset KeybAsciiMode
  282. KeybAsciiMode:
  283.         pushad
  284.         mov bl,1
  285.         mov edx,plaintty
  286.         call _SetIRQ
  287.         popad
  288.         ret
  289.  
  290.         public _KeybRawMode
  291. _KeybRawMode dd offset KeybRawMode
  292. KeybRawMode:
  293.         pushad
  294.         mov bl,1
  295.         mov edx,offset IRQ1_ISR
  296.         call _SetIRQ
  297.         popad
  298.         ret
  299.         
  300.         public _ScanKeyb
  301. _ScanKeyb dd offset ScanKeyb
  302. ScanKeyb:
  303.         mov eax,offset _RKB
  304.         ret
  305.         
  306.         public _ReadAscii
  307. _ReadAscii dd offset ReadAscii
  308. ReadAscii: ; out: eax = ascii char read from consolle
  309.         ; Be careful! this uses int 09 (irq 1)
  310.         ; so it needs _KeybAsciiMode !!!
  311.         push V86eax
  312. retry:        
  313.         mov eax,21h    ; get a key thru dos & reset upper bytes of eax
  314.         mov V86ah,07   ;
  315.         call _ExecINT        ;
  316.         mov al,V86al   ;
  317.         or al,al       ;
  318.         je retry       ; NUL character, retry
  319.         pop V86eax
  320.         ret
  321. code32  ends
  322.  
  323.         END
  324.